﻿
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace SharpSoft.Web
{
    using Microsoft.AspNetCore.Authentication;
    public static class HttpContextExtensions
    {
        /// <summary>
        /// 使用户登录
        /// </summary>
        /// <param name="context"></param>
        /// <param name="user"></param>
        /// <param name="cookieIsPersistent">是否持久保存Cookie</param>
        /// <returns></returns>
        public async static Task SignInAsync(this HttpContext context, AppUser user, bool cookieIsPersistent, string schema = null)
        {

            await context.SignInAsync(user, new AuthenticationProperties
            {
                IsPersistent = cookieIsPersistent,//cookies是否持久保存
                AllowRefresh = false, //是否允许刷新认证会话
            }, schema);
        }
        /// <summary>
        /// 使用户登录
        /// </summary>
        /// <param name="context"></param>
        /// <param name="user"></param>
        /// <param name="properties"></param>
        /// <param name="schema"></param>
        /// <returns></returns>
        public async static Task SignInAsync(this HttpContext context, AppUser user, AuthenticationProperties properties, string schema = null)
        {
            if (Startup.EnableRootUser)
            {//启用了根账户
                if (string.Compare(user.UserName, Startup.RootUserName, true) == 0)
                {//用户名与根账户名相同
                    //指明这是根账户
                    user.IsRootUser = true;
                }
            }
            var ci = CreateClaimsIdentity(user, schema);

            await context.SignInAsync(schema, new ClaimsPrincipal(ci), properties);
        }
        /// <summary>
        /// 从上下文获取当前用户信息
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static AppUser GetAppUser(this HttpContext context)
        {

            var User = context.User;
            if (User == null)
            {
                return null;
            }
            AppUser user = new AppUser();
            List<int> roles = new List<int>();
            foreach (var item in User.Claims)
            {
                switch (item.Type)
                {
                    case ClaimTypes.Name:
                        user.UserName = item.Value;
                        break;
                    case ClaimTypes.Role:
                        roles.Add(int.Parse(item.Value));
                        break;
                    case ClaimTypes.NameIdentifier:
                        user.UserId = int.Parse(item.Value);
                        break;
                    case "RoleFlag":
                        user.RoleFlag = int.Parse(item.Value);
                        break;
                    case "Permissions":
                        user.Permissions = item.Value;
                        break;
                    case AuthorizationService.RootUserClaimType:
                        user.IsRootUser = bool.Parse(item.Value);
                        break;
                    default:
                        break;
                }
            }
            user.Roles = roles.ToArray();
            return user;
        }


        #region 辅助方法

        private static ClaimsIdentity CreateClaimsIdentity(AppUser user, string schema = null)
        {
            if (schema == null)
            {
                schema = AuthorizationService.DefaultAuthenticationScheme;
            }
            var result = new ClaimsIdentity(schema);
            if (user.IsRootUser)
            {//根账号
                result.AddClaim(new Claim(AuthorizationService.RootUserClaimType, user.IsRootUser.ToString()));
            }
            if (user.Roles != null)
            {
                foreach (var item in user.Roles)
                {
                    result.AddClaim(new Claim(ClaimTypes.Role, item.ToString()));

                }
            }

            result.AddClaim(new Claim(ClaimTypes.Name, user.UserName ?? ""));
            result.AddClaim(new Claim("Ticket", user.Ticket ?? ""));
            result.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.UserId.ToString()));
            result.AddClaim(new Claim("DisplayName", user.DisplayName ?? ""));
            result.AddClaim(new Claim("RoleFlag", user.RoleFlag.ToString()));
            result.AddClaim(new Claim("Permissions", user.Permissions ?? ""));
            return result;
        }

        #endregion
    }

}
